/**
 * Author(s): xuming.Wong <xuming.Wong@gmail.com>
 */
#include "AssetWindow.h"

#include <QtCore/QUrl>
#include <QtGui/QLayout>
#include <QtGui/QMouseEvent>
#include <QtGui/QApplication>
#include <QtGui/QPushButton>
#include <QtGui/QFileDialog>
#include <QtGui/QToolBox>
#include <QtGui/QMessageBox>

#include "ProjectManager.h"
#include "PQEngine.h"

namespace PQBuilder
{
	AssetsTree::AssetsTree(QWidget *parent)
		: QTreeWidget(parent),_dialog(0)
	{
		setHeaderLabel(QObject::tr("Project Assets Achives"));
		setAcceptDrops(true);
		setDragDropMode(QAbstractItemView::DragDrop);
		setDropIndicatorShown(false);

		_dialog=new ArchiveDialog(this);
		connect(_dialog, SIGNAL(createArchiveSuccessed(QString)), this, SLOT(addArchive(QString)));

		loadArchives();
	}
	
	void AssetsTree::loadArchives()
	{
		//some default archive will be create when new scene object created
		//Small BUG:default archive not show first time
		int archiveCnt=ProjectManagerSingleton.getAssetArchiveCount();
		for(int i=0;i<archiveCnt;i++){
			std::string archiveName=ProjectManagerSingleton.getAssetArchiveName(i);
			QTreeWidgetItem* archiveItem=new QTreeWidgetItem(this,QStringList(QString::fromStdString(archiveName)));
			this->addTopLevelItem(archiveItem);

			int fileCnt=ProjectManagerSingleton.getAssetArchiveFileCount(i);
			for(int j=0;j<fileCnt;j++){
				std::string fileName=ProjectManagerSingleton.getAssetArchiveFileName(i,j);
				QTreeWidgetItem* fileItem=new QTreeWidgetItem(QStringList(QString::fromStdString(fileName)));
				archiveItem->addChild(fileItem);
			}

		}

	}

	
	void AssetsTree::mousePressEvent(QMouseEvent *evt)
	{
		QTreeWidget::mousePressEvent(evt);
		if (evt->button() == Qt::LeftButton){
			_dragStartPosition = evt->pos();
		}
	}

	void AssetsTree::contextMenuEvent(QContextMenuEvent *evt)
	{
		QTreeWidgetItem* item=this->itemAt(evt->pos());
		if(item){
			//top level item

			if(this->indexOfTopLevelItem(item)!=-1){
				QMenu menu(this);
				QAction* createFolderAction= menu.addAction(QObject::tr("Create folder"));
				QAction* addFileAction= menu.addAction(QObject::tr("Add file"));
				
				connect(addFileAction, SIGNAL(triggered()), this, SLOT(addFile()));

				menu.exec(evt->globalPos());
				return;
			}else{
				//file item in .gpk
				return;
			}
		}
		
		QMenu menu(this);
		QAction* createAction= menu.addAction(QObject::tr("Create empty archive"));
		QAction* importAction=menu.addAction(QObject::tr("Create archive from file folder"));
		
		connect(createAction, SIGNAL(triggered()), this, SLOT(createArchive()));
		connect(importAction, SIGNAL(triggered()), this, SLOT(importArchive()));

		
		menu.exec(evt->globalPos());
		
	 }

	void AssetsTree::dragEnterEvent(QDragEnterEvent *evt)
	{
		if (evt->mimeData()->hasFormat("text/uri-list")) {     
			evt->accept();
		}
		
	}

	void AssetsTree::dropEvent(QDropEvent *evt)
	{
		QTreeWidgetItem* item=this->itemAt(evt->pos());
		if(item){
			int index=this->indexOfTopLevelItem(item);
			if(index==-1){//not top level item file item
				return;
			}
			//top level item archive item
			if (evt->mimeData()->hasUrls()){
				QList<QUrl> urls = evt->mimeData()->urls(); // returns list of QUrl
				int size=urls.size();
				for(int i=0;i<size;i++){
					QString fileName=urls[i].toLocalFile();
					QFileInfo fileInfo(fileName);
					if(fileInfo.isFile()){
						bool succesed=ProjectManagerSingleton.addAssetArchiveFile(index,fileInfo.filePath().toStdString());
						if(succesed){
							QString fileName=fileInfo.fileName();
							QTreeWidgetItem* child=new QTreeWidgetItem(QStringList(fileName));
							item->addChild(child);
						}else{
							QMessageBox box;
							box.setText(QObject::tr("Fail to add file to asset archive."));
							box.exec();
						}
					}
				}
			}

			evt->acceptProposedAction();
			return;
			
		}
	}

	void AssetsTree::dragLeaveEvent(QDragLeaveEvent *evt)
	{
	}

	void AssetsTree::dragMoveEvent(QDragMoveEvent *evt)
	{
		if (evt->mimeData()->hasFormat("text/uri-list")) {
			QTreeWidgetItem* item=this->itemAt(evt->pos());
			if(item){
				int index=this->indexOfTopLevelItem(item);
				if(index!=-1){//top level item archive item
					setDropIndicatorShown(true);
					evt->accept();
					return;
				}
			}
		}
	}

	void AssetsTree::createArchive()
	{
		_dialog->show();

		
	}

	void AssetsTree::importArchive()
	{
		//_dialog->showOpen();
	}

	void AssetsTree::addFile()
	{
	}

	void AssetsTree::mouseMoveEvent(QMouseEvent *evt)
	{
		if (!(evt->buttons() & Qt::LeftButton)){
			return;
		}
		
		if ((evt->pos() - _dragStartPosition).manhattanLength()< QApplication::startDragDistance()){
			return;
		}
		
		QTreeWidgetItem *item=this->currentItem();
		if(item==0||item->childCount()>0){//only drag leaf item
			return;
		}

		QString path=getItemPath(item);

		assert(false);
		/*
		PQEngine::SerializeDatagram *datagram=GNgineExec::genAddGPKResoure(path.toStdString());
		
		QByteArray bytes=QByteArray(datagram->data(),datagram->length());
		QDrag *drag = new QDrag(this);
		QMimeData *mimeData = new QMimeData;
		mimeData->setData(QString::fromStdString(PQEngine::GameEngine::COMMAND_DATA_TYPE),bytes);
		drag->setMimeData(mimeData);
		Qt::DropAction dropAction = drag->exec(Qt::CopyAction | Qt::MoveAction);

		delete datagram;
		*/
	}

	QString AssetsTree::getItemPath(QTreeWidgetItem* item)
	{
		if(!item){
			return QString::null;
		}

		QTreeWidgetItem* parent=item->parent();
		std::vector<QTreeWidgetItem*> list;

		while(parent!=0){
			list.push_back(parent);
			parent=parent->parent();
		}

		QString path;
		int size=list.size();
		if(size==0){
			path=item->text(0);
		}else{
			for(int i=size-1;i>=0;i--){
				path+=list[i]->text(0);
				path+="/";
			}
			path+=item->text(0);
		}
		return path;
	}

	void AssetsTree::addArchive(QString archiveName)
	{
		QTreeWidgetItem* archiveItem=new QTreeWidgetItem(this,QStringList(archiveName));
		this->addTopLevelItem(archiveItem);
	}

	AssetWindow::AssetWindow(QWidget *parent)
	{
		setAcceptDrops(true);
		_treeWidget = new AssetsTree(this);

		QVBoxLayout *boxlayout = new QVBoxLayout(this);
		boxlayout->setMargin(0);
		boxlayout->addWidget(_treeWidget);
		boxlayout->setStretch(0,0);
		boxlayout->setStretch(1,1);
	}

	AssetWindow::~AssetWindow()
	{
	}

	

}
